﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Globalization;

namespace remes.BLoc
{
   public class BLocXmlTranslationDictionary : IAutoTranslationDictionary
   {
      public BLocXmlTranslationDictionary(string path)
      {
         Load(path);
      }

      private void Load(string path)
      {
         var xDoc = XDocument.Load(path);

         foreach (var xText in xDoc.Root.Descendants("Text"))
         {
            try
            {
               var sourceCulture = CultureInfo.GetCultureInfo((string)xText.Attribute("SourceCulture"));
               var targetCulture = CultureInfo.GetCultureInfo((string)xText.Attribute("TargetCulture"));
               bool bidirectional = Boolean.Parse((string)xText.Attribute("Bidirectional") ?? "False");
               var sourceText = (string)xText.Attribute("Source");
               var targetText = (string)xText.Attribute("Target");
               if (!String.IsNullOrWhiteSpace(sourceText) && !String.IsNullOrWhiteSpace(targetText))
               {
                  AddText(sourceCulture, sourceText, targetCulture, targetText);

                  if (bidirectional)
                  {
                     AddText(targetCulture, targetText, sourceCulture, sourceText);
                  }
               }
            }
            catch { }
         }
      }

      private void AddText(CultureInfo sourceCulture, string sourceText, CultureInfo targetCulture, string targetText)
      {
         Dictionary<string, Dictionary<string, string>> sourceCultureDict;
         if (!_Texts.TryGetValue(sourceCulture.Name, out sourceCultureDict))
         {
            sourceCultureDict = new Dictionary<string, Dictionary<string, string>>();
            _Texts.Add(sourceCulture.Name, sourceCultureDict);
         }

         Dictionary<string, string> targetCultureDict;
         if (!sourceCultureDict.TryGetValue(targetCulture.Name, out targetCultureDict))
         {
            targetCultureDict = new Dictionary<string, string>();
            sourceCultureDict.Add(targetCulture.Name, targetCultureDict);
         }

         if (!targetCultureDict.ContainsKey(sourceText))
         {
            targetCultureDict.Add(sourceText, targetText);
         }
      }

      private Dictionary<string, Dictionary<string, Dictionary<string, string>>> _Texts = new Dictionary<string,Dictionary<string,Dictionary<string,string>>>();

      #region IAutoTranslationDictionary Members

      public IEnumerable<string> GetSourceCultures()
      {
         return _Texts.Keys;
      }

      public IEnumerable<string> GetTargetCultures(string sourceCulture)
      {
         if (_Texts.ContainsKey(sourceCulture))
         {
            return _Texts[sourceCulture].Keys;
         }
         return new List<string>();
      }

      public string Translate(CultureInfo sourceCulture, string sourceText, CultureInfo targetCulture, bool doPartialTranslations)
      {
         Dictionary<string, Dictionary<string, string>> sourceCultureDict;
         if (_Texts.TryGetValue(sourceCulture.Name, out sourceCultureDict))
         {
            Dictionary<string, string> targetCultureDict;
            if (sourceCultureDict.TryGetValue(targetCulture.Name, out targetCultureDict))
            {
               if (doPartialTranslations)
               {
                  var sources = new List<string>(targetCultureDict.Keys);
                  // sort by length
                  sources.Sort(new Comparison<string>((s1, s2) =>
                     {
                        if (s1.Length < s2.Length)
                        {
                           return -1;
                        }
                        else if (s1.Length > s2.Length)
                        {
                           return 1;
                        }
                        else
                        {
                           return 0;
                        }
                     }));

                  System.Diagnostics.Debug.Assert(false, "Check if list is sorted correctly (longest strings first!");

                  string targetText = sourceText;
                  foreach (var s in sources)
                  {
                     targetText = targetText.Replace(s, targetCultureDict[s]);
                  }
                  if (String.Compare(targetText, sourceText) == 0)
                  {
                     // no changes
                     return null;
                  }
                  return targetText;
               }
               else
               {
                  if (targetCultureDict.ContainsKey(sourceText))
                  {
                     return targetCultureDict[sourceText];
                  }
               }
            }
         }

         return null;
      }

      #endregion
   }
}
